package com.example.cut_game2;
import android.os.Bundle;
import android.app.Activity;
import android.util.FloatMath;
import android.util.Log;
import android.view.Menu;
 
 
import java.io.IOException;
 
import org.andengine.audio.music.Music;
import org.andengine.audio.music.MusicFactory;
 
import org.andengine.audio.music.Music;
import org.andengine.audio.music.MusicFactory;
import org.andengine.audio.sound.Sound;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.Engine;
import org.andengine.engine.FixedStepEngine;
import org.andengine.engine.camera.BoundCamera;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.WakeLockOptions;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.primitive.Line;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.text.Text;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.font.Font;
import org.andengine.opengl.font.FontFactory;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import android.graphics.Color;
import org.andengine.engine.camera.hud.HUD;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.text.Text;
import org.andengine.entity.text.TextOptions;
import org.andengine.opengl.font.Font;
import org.andengine.opengl.font.FontFactory;
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.util.GLState;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.math.MathConstants;
import org.andengine.util.math.MathUtils;
 
import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.util.Vector2Pool;
import org.andengine.extension.physics.box2d.util.constants.PhysicsConstants;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import org.andengine.input.touch.TouchEvent;
import org.andengine.input.touch.detector.ContinuousHoldDetector;
import org.andengine.input.touch.detector.HoldDetector;
import org.andengine.input.touch.detector.HoldDetector.IHoldDetectorListener;
 
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.Joint;
import com.badlogic.gdx.physics.box2d.Manifold;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.RayCastCallback;
import com.badlogic.gdx.physics.box2d.joints.DistanceJointDef;
import com.badlogic.gdx.physics.box2d.joints.LineJointDef;
import com.badlogic.gdx.physics.box2d.joints.MouseJoint;
import com.badlogic.gdx.physics.box2d.joints.MouseJointDef;
import com.badlogic.gdx.physics.box2d.joints.PrismaticJointDef;
import com.badlogic.gdx.physics.box2d.joints.PulleyJointDef;
import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef;
import com.badlogic.gdx.physics.box2d.joints.WeldJointDef;
 
 
import android.graphics.Typeface;
import android.hardware.SensorManager;
import android.widget.Toast;
 
public class test extends SimpleBaseGameActivity implements
        IAccelerationListener, IOnSceneTouchListener {
 
     
    public static int cameraWidth = 800;
    public static int cameraHeight = 480;
    public Scene mScene;
    public FixedStepPhysicsWorld mPhysicsWorld;
     
    Body BoxBody;
    Line RayCastLine;
    Line RayCastLineHitNormal;
    Line RayCastLineHitBounce;
    float[] RayCastStart = {cameraWidth/2f,15f};
    float RayCastAngle = 0f;
    float RayCastNormalAngle = 0f;
    float RayCastBounceAngle = 0f;
    float RaycastBounceLineLength = 200f;
    final FixtureDef boxFixtureDef =
    PhysicsFactory.createFixtureDef(1f, 0.5f, 0.9f);
     
     
RayCastCallback rayCastCallBack = new RayCastCallback() {
         
        @Override

        public float reportRayFixture(Fixture fixture, Vector2 point,
                Vector2 normal, float fraction) {
            Log.d("fuck", "hhh");
            // TODO Auto-generated method stub
            float[] linePos = {
                    point.x *
                    PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
                    point.y *
                    PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
                    (point.x + (normal.x)) *
                    PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
                    (point.y + (normal.y)) *
                    PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT};
                    RayCastLineHitNormal.setPosition(
                    linePos[0],linePos[1],
                    linePos[2],linePos[3]);
                    RayCastLineHitNormal.setVisible(true);
                     
RayCastNormalAngle = MathUtils.radToDeg(
                            (float) Math.atan2(
                            linePos[3]-linePos[1],
                            linePos[2]-linePos[0]));
RayCastBounceAngle = (2*RayCastNormalAngle)-RayCastAngle;
                            RayCastLineHitBounce.setPosition(
                        linePos[0], linePos[1],
                            (linePos[0] + FloatMath.cos((RayCastBounceAngle + 180f) *
                MathConstants.DEG_TO_RAD) * RaycastBounceLineLength),
                            (linePos[1] + FloatMath.sin((RayCastBounceAngle + 180f) *
                            MathConstants.DEG_TO_RAD)*RaycastBounceLineLength));
        RayCastLineHitBounce.setVisible(true);
                            return 0f;
             
             
             
             
        }
                };
 
    @Override
    public Engine onCreateEngine(final EngineOptions pEngineOptions) {
        return new FixedStepEngine(pEngineOptions, 60);
 
    }
 
    @Override
    public EngineOptions onCreateEngineOptions() {
 
        EngineOptions engineOptions = new EngineOptions(true,
                ScreenOrientation.LANDSCAPE_SENSOR, new FillResolutionPolicy(),
                new Camera(0, 0, cameraWidth, cameraHeight));
 
        engineOptions.getRenderOptions().setDithering(true);
        //((Object) engineOptions.getRenderOptions()).getConfigChooserOptions()
          //      .setRequestedMultiSampling(true);
        engineOptions.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
 
        return engineOptions;
    }
 
    @Override
    protected void onCreateResources() {
 
        // TODO Auto-generated method stub
 
    }
     
    @Override
    protected Scene onCreateScene() {
        mScene = new Scene();
        mScene.setBackground(new Background(0.9f,0.9f,0.9f));
         
        mPhysicsWorld = new FixedStepPhysicsWorld(60, new
                Vector2(0f,-SensorManager.GRAVITY_EARTH*2),false, 8, 3);
                mScene.registerUpdateHandler(mPhysicsWorld);
         
         
Rectangle Box1 = new Rectangle(400f, 350f, 200f, 200f,this.getEngine().getVertexBufferObjectManager());
                        Box1.setColor(0.3f, 0.3f, 0.3f);
    BoxBody = PhysicsFactory.createBoxBody(mPhysicsWorld, Box1,BodyType.StaticBody, boxFixtureDef);
    BoxBody.setTransform(BoxBody.getWorldCenter(), MathUtils.random(0.349f, 1.222f));
                        mScene.attachChild(Box1);
    mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(Box1, BoxBody));
         
 
    Rectangle Box2 = new Rectangle(300f, 50f, 200f, 50f,this.getEngine().getVertexBufferObjectManager());
    Box2.setColor(0.3f, 0.3f, 0.3f);
BoxBody = PhysicsFactory.createBoxBody(mPhysicsWorld, Box2,BodyType.StaticBody, boxFixtureDef);

    mScene.attachChild(Box2);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(Box2, BoxBody));
    
    
    
    RayCastLine = new Line(0f, 0f, 0f, 0f,mEngine.getVertexBufferObjectManager());
            RayCastLine.setColor(0f, 1f, 0f);
        RayCastLine.setLineWidth(8f);
                mScene.attachChild(RayCastLine);
        RayCastLineHitNormal = new Line(0f, 0f, 0f, 0f,mEngine.getVertexBufferObjectManager());
             
        RayCastLineHitNormal.setColor(1f, 0f, 0f);
             
            RayCastLineHitNormal.setLineWidth(8f);
             
            mScene.attachChild(RayCastLineHitNormal);
             
RayCastLineHitBounce = new Line(0f, 0f, 0f, 0f,mEngine.getVertexBufferObjectManager());
            RayCastLineHitBounce.setColor(0f, 0f, 1f);
        RayCastLineHitBounce.setLineWidth(8f);
    mScene.attachChild(RayCastLineHitBounce);
     
        mScene.setOnSceneTouchListener(this);
                 
     
     
         
                             
 
return mScene;
    }
 
    @Override
    public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public void onAccelerationChanged(AccelerationData pAccelerationData) {
        // TODO Auto-generated method stub
 
        /*final Vector2 gravity = Vector2Pool.obtain(
                pAccelerationData.getX(),
                pAccelerationData.getY());
                this.mPhysicsWorld.setGravity(gravity);
                Vector2Pool.recycle(gravity);*/
 
    }
 
    @Override
    public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
        // TODO Auto-generated method stub
         
        if(pSceneTouchEvent.
                isActionDown()){
        RayCastAngle = MathUtils.radToDeg((float)
                 Math.atan2(pSceneTouchEvent.getY() - RayCastStart[1],
            pSceneTouchEvent.getX() - RayCastStart[0]));
        RayCastLine.setPosition(
                 RayCastStart[0], RayCastStart[1],
                   pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
                    RayCastLine.setVisible(true);
                RayCastLineHitNormal.setVisible(false);
                 
                RayCastLineHitBounce.setVisible(false);
                    mPhysicsWorld.rayCast(rayCastCallBack,
                    new Vector2(
                        RayCastStart[0] /
                PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
                RayCastStart[1] /
                 
                PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT),
                new Vector2(
                pSceneTouchEvent.getX() /
                 
                PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
                 
                pSceneTouchEvent.getY() /
                 
                PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
                 
        }
    if(pSceneTouchEvent.isActionUp() ||pSceneTouchEvent.isActionOutside() ||
                pSceneTouchEvent.isActionCancel())
                {
                RayCastLine.setVisible(false);
                }
 
         
        return false; 
 
    }
 
     
 
    @Override
    public void onResumeGame() {
 
        super.onResumeGame();
 
        this.enableAccelerationSensor(this);
 
    }
 
    @Override
    public void onPauseGame() {
 
        super.onPauseGame();
 
        this.disableAccelerationSensor();
    }
     
}